package patternmining.model.construction;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.antlr.runtime.ANTLRInputStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.CommonTreeNodeStream;



/** An instance of JavaSourceFile represent ONE source file of java code.
 *  Several files of java code constitute a JavaSourceGroup, a project that jointly
 *  may be analiezed to extract the model data contained in the java sources and might be represented by a joined graph.
 *
 *  The object modelable as a graph is the JavaSourceGroup. To represent a single source file as a graph create a group that
 *  contains only one JavaSourceFile:
 * 
 *  Usage:
 *  JavaSourceFile is used only by the JavaSourceGroup class.
 *  Use JavaSourceGroup's API
 *  
 * @version 1.0, 09.05.2008
 * @author Holger Wiehen
 */
class JavaSourceFile {

    private File source;
    private CommonTree ast;
    private CommonTokenStream tokenStream;
    
    //object offers operations to map the short name of types to its qualified version 
    TypeNameQualifier typeNameQualifier;
    //object offers operations to map this java source files attribute name to it's type
    AttributeTypeResolver attributeResolver;
    
    public JavaSourceFile(File file) throws IOException, WrongFileTypeException{
         if ( file.isFile() && Source.isJavaSourceFile(file) )
            source = file;
        else
            throw new WrongFileTypeException("File " + file.getCanonicalPath() + " is not a JavaSourceFile");
    }
    
    /**Construction of the AST associated to this object's java source file
     * 
     * @throws java.io.IOException
     * @throws org.antlr.runtime.RecognitionException
     */
    public void first_construct_AST() throws IOException, RecognitionException{
        FileInputStream input = new FileInputStream(source);
        ANTLRInputStream antlrInput = new ANTLRInputStream(input);
        JavaLexer lexer = new JavaLexer(antlrInput);
        tokenStream = new CommonTokenStream(lexer);
        JavaParser parser = new JavaParser( tokenStream );
        ast = (CommonTree) parser.javaSource().getTree(); 
    }
    
    /**Analysis of this java source file's AST for the defined package and the defined type's ( class, interface or enum )
     * Adding the obtained information to a mapping object ( package -> members of package )
     * shared by the following analysis fases of all ASTs forming the java source group ( the group of java source files to model joinedly with one graph ) 
     * 
     * @throws java.io.IOException
     * @throws org.antlr.runtime.RecognitionException
     */
    public PackageIndex second_completePackageIndex( PackageIndex definedPackages)throws RecognitionException{
        CommonTreeNodeStream treeNodes = new CommonTreeNodeStream(ast);
        treeNodes.setTokenStream(tokenStream);
        JavaASTFirstPass firstPass = new JavaASTFirstPass(treeNodes, definedPackages);
        firstPass.javaSource();
        definedPackages = firstPass.getPackageMapping();
        return definedPackages;
    }
    
    /**Analysis of this object's AST to extract to extract some information used in the following analysis step
     * -> Construction of a table mapping this java source files short type names to its qualified version
     * -> Construction of a table mapping this java source files atributes to its type;
     * -> Construction of a unique name for each method in this java source file, resolving this way overloading issues, and adding the information
     *    to a mapping shared by the following analysis step of all ASTs ( mapping: method_name, parameter_list -> unique_method_name )
     */
    public MethodNameResolver third_constructMemberTable(PackageIndex definedPackages, MethodNameResolver methodResolver) throws RecognitionException{
        CommonTreeNodeStream treeNodes = new CommonTreeNodeStream(ast);
        treeNodes.setTokenStream(tokenStream);
        JavaASTSecondPass secondPass = new JavaASTSecondPass(treeNodes, definedPackages, methodResolver);
        secondPass.javaSource();
        typeNameQualifier = secondPass.getTypeNameQualifier();
        attributeResolver = secondPass.getAttributeTypeResolver();
        attributeResolver.test();
        methodResolver = secondPass.getMethodNameResolver();
        return methodResolver;
    }
    
    /**Analysis of this object's AST to extract it's element to be modeled by the graph model
     * Addition of the encountered information to a container object, whose content will be mereged with the information
     * encountered in the outher java source files of the source group to build the group's complete model
     * 
     */
    public ModelData forth_extractModelData( MethodNameResolver methodResolver )throws RecognitionException{
        CommonTreeNodeStream treeNodes = new CommonTreeNodeStream(ast);
        treeNodes.setTokenStream(tokenStream);
        JavaASTThirdPass thirdPass = new JavaASTThirdPass(treeNodes, typeNameQualifier, attributeResolver, methodResolver );
        ModelData modelData = new ModelData();
        thirdPass.javaSource();
        modelData = thirdPass.getModelData();
        return modelData;
       
    }
    
}
